import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../../../common/models/server_model.dart';
import '../../../common/services/server_service.dart';
import '../../../common/utils/index.dart';

/// Docker 容器信息
class DockerContainer {
  final String id;
  final String name;
  final String image;
  final String status;
  final String created;
  final String ports;
  final Map<String, String> labels; // 容器标签
  
  DockerContainer({
    required this.id,
    required this.name,
    required this.image,
    required this.status,
    required this.created,
    required this.ports,
    this.labels = const {},
  });
  
  bool get isRunning => status.toLowerCase().contains('up');
  bool get canStart => !isRunning;
  bool get canStop => isRunning;
  
  /// 是否是 Docker Compose 容器
  bool get isComposeContainer => 
    labels.containsKey('com.docker.compose.project') ||
    labels.containsKey('com.docker.compose.service');
  
  /// 获取 Compose 项目名称
  String? get composeProject => labels['com.docker.compose.project'];
  
  /// 获取 Compose 服务名称
  String? get composeService => labels['com.docker.compose.service'];
  
  /// 获取 Compose 配置文件路径
  String? get composeConfigFile => labels['com.docker.compose.project.config_files'];
  
  /// 获取 Compose 工作目录
  String? get composeWorkingDir => labels['com.docker.compose.project.working_dir'];
  
  /// 从 docker ps JSON 输出解析
  factory DockerContainer.fromJson(Map<String, dynamic> json) {
    // 解析标签
    final labelsStr = json['Labels'] ?? '';
    final labels = <String, String>{};
    if (labelsStr is String && labelsStr.isNotEmpty) {
      // Labels 格式: "key1=value1,key2=value2"
      for (final label in labelsStr.split(',')) {
        final parts = label.split('=');
        if (parts.length == 2) {
          labels[parts[0]] = parts[1];
        }
      }
    }
    
    return DockerContainer(
      id: json['ID'] ?? json['id'] ?? '',
      name: json['Names'] ?? json['name'] ?? '',
      image: json['Image'] ?? json['image'] ?? '',
      status: json['Status'] ?? json['status'] ?? '',
      created: json['Created'] ?? json['created'] ?? '',
      ports: json['Ports'] ?? json['ports'] ?? '',
      labels: labels,
    );
  }
}

class ServerDockerController extends GetxController {
  final ServerService _serverService = Get.find<ServerService>();
  late final String serverId;
  
  Rx<ServerModel?> server = Rx<ServerModel?>(null);
  RxList<DockerContainer> containers = <DockerContainer>[].obs;
  
  RxBool isLoading = false.obs;
  RxBool isRefreshing = false.obs;
  RxString errorMessage = ''.obs;
  
  // 状态监听订阅
  StreamSubscription<ServerModel>? _stateSubscription;
  
  // 自动刷新定时器
  Timer? _refreshTimer;
  RxBool autoRefresh = false.obs;
  RxInt refreshInterval = 10.obs; // 刷新间隔（秒）
  
  // Docker Compose 相关
  RxBool hasDockerCompose = false.obs; // 是否支持 docker-compose
  RxBool groupByCompose = false.obs; // 是否按 Compose 项目分组显示
  RxMap<String, bool> projectExpandedStates = <String, bool>{}.obs; // 项目展开状态
  
  /// 获取所有 Compose 项目名称
  List<String> get composeProjects {
    final projects = <String>{};
    for (final container in containers) {
      if (container.composeProject != null) {
        projects.add(container.composeProject!);
      }
    }
    return projects.toList()..sort();
  }
  
  /// 切换项目展开状态
  void toggleProjectExpanded(String projectName) {
    final currentState = projectExpandedStates[projectName] ?? true;
    projectExpandedStates[projectName] = !currentState;
  }
  
  /// 获取项目展开状态
  bool isProjectExpanded(String projectName) {
    return projectExpandedStates[projectName] ?? true; // 默认展开
  }
  
  /// 根据项目名获取容器列表
  List<DockerContainer> getContainersByProject(String project) {
    return containers.where((c) => c.composeProject == project).toList();
  }
  
  /// 获取非 Compose 容器
  List<DockerContainer> get standaloneContainers {
    return containers.where((c) => !c.isComposeContainer).toList();
  }

  @override
  void onInit() {
    super.onInit();
    debugPrint('🎬 ServerDockerController: onInit');
    
    serverId = Get.parameters['id'] ?? '';
    debugPrint('   服务器ID: $serverId');
    
    if (serverId.isEmpty) {
      debugPrint('❌ ServerDockerController: 服务器 ID 为空');
      LoadingUtil.error('服务器 ID 无效');
      Get.back();
      return;
    }
    
    _loadServer();
    _listenToServerStateChanges();
  }

  /// 监听服务器状态变化
  void _listenToServerStateChanges() {
    debugPrint('👂 ServerDockerController: 开始监听服务器状态变化');
    _stateSubscription = _serverService.watchServer(serverId).listen((updatedServer) {
      debugPrint('📢 ServerDockerController: 收到服务器状态更新');
      server.value = updatedServer;
    });
  }

  /// 加载服务器信息
  Future<void> _loadServer() async {
    debugPrint('📋 ServerDockerController: 加载服务器信息');
    
    server.value = _serverService.getServer(serverId);
    if (server.value == null) {
      debugPrint('❌ ServerDockerController: 服务器不存在');
      LoadingUtil.error('服务器不存在');
      Get.back();
      return;
    }
    
    // 检查是否已连接
    if (_serverService.isConnected(serverId)) {
      debugPrint('🔗 ServerDockerController: 服务器已连接，加载容器列表');
      await loadContainers();
    } else {
      debugPrint('⚠️ ServerDockerController: 服务器未连接');
      errorMessage.value = '服务器未连接，请先连接服务器';
    }
  }

  /// 检测 Docker Compose 是否可用
  Future<void> _checkDockerCompose() async {
    try {
      final client = _serverService.getClient(serverId);
      if (client == null) return;
      
      // 尝试 docker-compose --version 或 docker compose version
      final result1 = await client.run('command -v docker-compose').timeout(
        const Duration(seconds: 3),
        onTimeout: () => Uint8List(0),
      );
      final result2 = await client.run('docker compose version').timeout(
        const Duration(seconds: 3),
        onTimeout: () => Uint8List(0),
      );
      
      hasDockerCompose.value = result1.isNotEmpty || result2.isNotEmpty;
      debugPrint('🔍 Docker Compose 检测: ${hasDockerCompose.value ? "已安装" : "未安装"}');
    } catch (e) {
      hasDockerCompose.value = false;
      debugPrint('⚠️ Docker Compose 检测失败: $e');
    }
  }

  /// 加载 Docker 容器列表
  Future<void> loadContainers({bool showLoading = true}) async {
    if (!_serverService.isConnected(serverId)) {
      debugPrint('❌ ServerDockerController: 服务器未连接');
      errorMessage.value = '服务器未连接';
      return;
    }
    
    if (showLoading) {
      isLoading.value = true;
    } else {
      isRefreshing.value = true;
    }
    errorMessage.value = '';
    
    try {
      debugPrint('🐋 ServerDockerController: 获取 Docker 容器列表...');
      
      final client = _serverService.getClient(serverId);
      if (client == null) {
        throw Exception('无法获取 SSH 客户端');
      }
      
      // 检测 Docker Compose
      await _checkDockerCompose();
      
      // 执行 docker ps -a 命令（获取所有容器，包括停止的）
      final cmd = 'docker ps -a --format "{{json .}}"';
      debugPrint('📝 执行命令: $cmd');
      
      final result = await client.run(cmd);
      final output = utf8.decode(result);
      
      debugPrint('📄 Docker 输出: ${output.substring(0, output.length > 200 ? 200 : output.length)}...');
      
      if (output.contains('docker: command not found') || 
          output.contains('Cannot connect to the Docker daemon')) {
        debugPrint('⚠️ Docker 未安装或未运行');
        errorMessage.value = 'Docker 未安装或未运行';
        containers.clear();
        return;
      }
      
      // 解析 JSON 输出
      final lines = output.trim().split('\n').where((l) => l.isNotEmpty).toList();
      final parsedContainers = <DockerContainer>[];
      
      for (final line in lines) {
        try {
          final json = jsonDecode(line) as Map<String, dynamic>;
          parsedContainers.add(DockerContainer.fromJson(json));
        } catch (e) {
          debugPrint('⚠️ 解析容器数据失败: $e');
        }
      }
      
      containers.value = parsedContainers;
      
      // 统计 Compose 容器
      final composeCount = containers.where((c) => c.isComposeContainer).length;
      debugPrint('✅ ServerDockerController: 容器列表加载成功');
      debugPrint('   总数: ${containers.length} | Compose: $composeCount | 独立: ${containers.length - composeCount}');
      
      // 如果有 Compose 容器，默认启用分组视图
      if (composeCount > 0 && !groupByCompose.value) {
        groupByCompose.value = true;
        debugPrint('🔵 自动启用 Compose 分组视图');
      }
      
    } catch (e) {
      errorMessage.value = e.toString();
      debugPrint('❌ ServerDockerController: 加载容器列表失败 - $e');
    } finally {
      isLoading.value = false;
      isRefreshing.value = false;
    }
  }

  /// 启动容器
  Future<void> startContainer(DockerContainer container) async {
    debugPrint('▶️ ServerDockerController: 启动容器 ${container.name}');
    
    try {
      LoadingUtil.show('正在启动容器...');
      
      final client = _serverService.getClient(serverId);
      if (client == null) throw Exception('无法获取 SSH 客户端');
      
      final cmd = 'docker start ${container.id}';
      await client.run(cmd);
      
      debugPrint('✅ 容器启动成功');
      LoadingUtil.success('容器启动成功');
      
      // 刷新列表
      await loadContainers(showLoading: false);
    } catch (e) {
      debugPrint('❌ 启动容器失败: $e');
      LoadingUtil.error('启动失败: $e');
    }
  }

  /// 停止容器
  Future<void> stopContainer(DockerContainer container) async {
    debugPrint('⏹️ ServerDockerController: 停止容器 ${container.name}');
    
    try {
      LoadingUtil.show('正在停止容器...');
      
      final client = _serverService.getClient(serverId);
      if (client == null) throw Exception('无法获取 SSH 客户端');
      
      final cmd = 'docker stop ${container.id}';
      await client.run(cmd);
      
      debugPrint('✅ 容器停止成功');
      LoadingUtil.success('容器停止成功');
      
      // 刷新列表
      await loadContainers(showLoading: false);
    } catch (e) {
      debugPrint('❌ 停止容器失败: $e');
      LoadingUtil.error('停止失败: $e');
    }
  }

  /// 重启容器
  Future<void> restartContainer(DockerContainer container) async {
    debugPrint('🔄 ServerDockerController: 重启容器 ${container.name}');
    
    try {
      LoadingUtil.show('正在重启容器...');
      
      final client = _serverService.getClient(serverId);
      if (client == null) throw Exception('无法获取 SSH 客户端');
      
      final cmd = 'docker restart ${container.id}';
      await client.run(cmd);
      
      debugPrint('✅ 容器重启成功');
      LoadingUtil.success('容器重启成功');
      
      // 刷新列表
      await loadContainers(showLoading: false);
    } catch (e) {
      debugPrint('❌ 重启容器失败: $e');
      LoadingUtil.error('重启失败: $e');
    }
  }

  /// 删除容器
  Future<void> deleteContainer(DockerContainer container) async {
    final confirmed = await Get.dialog<bool>(
      AlertDialog(
        title: const Text('确认删除'),
        content: Text('确定要删除容器 "${container.name}" 吗？\n\n容器ID: ${container.id.substring(0, 12)}'),
        actions: [
          TextButton(
            onPressed: () => Get.back(result: false),
            child: const Text('取消'),
          ),
          TextButton(
            onPressed: () => Get.back(result: true),
            style: TextButton.styleFrom(foregroundColor: Colors.red),
            child: const Text('删除'),
          ),
        ],
      ),
    );

    if (confirmed == true) {
      debugPrint('🗑️ ServerDockerController: 删除容器 ${container.name}');
      
      try {
        LoadingUtil.show('正在删除容器...');
        
        final client = _serverService.getClient(serverId);
        if (client == null) throw Exception('无法获取 SSH 客户端');
        
        // 如果容器正在运行，先停止
        if (container.isRunning) {
          await client.run('docker stop ${container.id}');
        }
        
        // 删除容器
        final cmd = 'docker rm ${container.id}';
        await client.run(cmd);
        
        debugPrint('✅ 容器删除成功');
        LoadingUtil.success('容器删除成功');
        
        // 刷新列表
        await loadContainers(showLoading: false);
      } catch (e) {
        debugPrint('❌ 删除容器失败: $e');
        LoadingUtil.error('删除失败: $e');
      }
    }
  }

  /// 切换自动刷新
  void toggleAutoRefresh(bool value) {
    autoRefresh.value = value;
    debugPrint('🔄 ServerDockerController: 自动刷新 ${value ? "开启" : "关闭"}');
    
    if (value) {
      _startAutoRefresh();
    } else {
      _refreshTimer?.cancel();
    }
  }

  /// 启动自动刷新
  void _startAutoRefresh() {
    _refreshTimer?.cancel();
    _refreshTimer = Timer.periodic(
      Duration(seconds: refreshInterval.value),
      (timer) {
        if (autoRefresh.value && _serverService.isConnected(serverId)) {
          loadContainers(showLoading: false);
        }
      },
    );
    debugPrint('⏰ ServerDockerController: 启动自动刷新 - 间隔: ${refreshInterval.value}秒');
  }

  /// 设置刷新间隔
  void setRefreshInterval(int seconds) {
    refreshInterval.value = seconds;
    debugPrint('⏱️ ServerDockerController: 刷新间隔设置为 ${seconds}秒');
    
    if (autoRefresh.value) {
      _startAutoRefresh();
    }
  }

  // ==================== Docker Compose 项目操作 ====================
  
  /// 获取 docker-compose 命令（自动检测版本）
  Future<String> _getComposeCommand() async {
    if (!hasDockerCompose.value) {
      throw Exception('Docker Compose 未安装');
    }
    
    final client = _serverService.getClient(serverId);
    if (client == null) throw Exception('无法获取 SSH 客户端');
    
    // 检查是否支持 docker compose (新版本)
    try {
      await client.run('docker compose version').timeout(const Duration(seconds: 2));
      return 'docker compose';
    } catch (_) {
      return 'docker-compose';
    }
  }
  
  /// 启动 Compose 项目
  Future<void> startComposeProject(String projectName) async {
    debugPrint('🚀 ServerDockerController: 启动 Compose 项目 - $projectName');
    
    try {
      LoadingUtil.show('正在启动项目...');
      
      final client = _serverService.getClient(serverId);
      if (client == null) throw Exception('无法获取 SSH 客户端');
      
      // 获取项目的工作目录
      final container = containers.firstWhere((c) => c.composeProject == projectName);
      final workDir = container.composeWorkingDir;
      
      if (workDir == null || workDir.isEmpty) {
        throw Exception('无法获取项目工作目录');
      }
      
      final composeCmd = await _getComposeCommand();
      final cmd = 'cd "$workDir" && $composeCmd up -d';
      debugPrint('📝 执行命令: $cmd');
      
      await client.run(cmd);
      
      debugPrint('✅ Compose 项目启动成功');
      LoadingUtil.success('项目启动成功');
      
      // 延迟刷新，等待容器启动
      await Future.delayed(const Duration(seconds: 2));
      await loadContainers(showLoading: false);
    } catch (e) {
      debugPrint('❌ 启动 Compose 项目失败: $e');
      LoadingUtil.error('启动失败: $e');
    }
  }
  
  /// 停止 Compose 项目
  Future<void> stopComposeProject(String projectName) async {
    debugPrint('⏹️ ServerDockerController: 停止 Compose 项目 - $projectName');
    
    try {
      LoadingUtil.show('正在停止项目...');
      
      final client = _serverService.getClient(serverId);
      if (client == null) throw Exception('无法获取 SSH 客户端');
      
      final container = containers.firstWhere((c) => c.composeProject == projectName);
      final workDir = container.composeWorkingDir;
      
      if (workDir == null || workDir.isEmpty) {
        throw Exception('无法获取项目工作目录');
      }
      
      final composeCmd = await _getComposeCommand();
      final cmd = 'cd "$workDir" && $composeCmd stop';
      debugPrint('📝 执行命令: $cmd');
      
      await client.run(cmd);
      
      debugPrint('✅ Compose 项目停止成功');
      LoadingUtil.success('项目停止成功');
      
      await loadContainers(showLoading: false);
    } catch (e) {
      debugPrint('❌ 停止 Compose 项目失败: $e');
      LoadingUtil.error('停止失败: $e');
    }
  }
  
  /// 重启 Compose 项目
  Future<void> restartComposeProject(String projectName) async {
    debugPrint('🔄 ServerDockerController: 重启 Compose 项目 - $projectName');
    
    try {
      LoadingUtil.show('正在重启项目...');
      
      final client = _serverService.getClient(serverId);
      if (client == null) throw Exception('无法获取 SSH 客户端');
      
      final container = containers.firstWhere((c) => c.composeProject == projectName);
      final workDir = container.composeWorkingDir;
      
      if (workDir == null || workDir.isEmpty) {
        throw Exception('无法获取项目工作目录');
      }
      
      final composeCmd = await _getComposeCommand();
      final cmd = 'cd "$workDir" && $composeCmd restart';
      debugPrint('📝 执行命令: $cmd');
      
      await client.run(cmd);
      
      debugPrint('✅ Compose 项目重启成功');
      LoadingUtil.success('项目重启成功');
      
      await Future.delayed(const Duration(seconds: 2));
      await loadContainers(showLoading: false);
    } catch (e) {
      debugPrint('❌ 重启 Compose 项目失败: $e');
      LoadingUtil.error('重启失败: $e');
    }
  }
  
  /// 删除 Compose 项目（停止并删除容器）
  Future<void> deleteComposeProject(String projectName) async {
    final confirmed = await Get.dialog<bool>(
      AlertDialog(
        title: const Text('确认删除'),
        content: Text('确定要删除 Compose 项目 "$projectName" 吗？\n\n这将停止并删除该项目的所有容器。'),
        actions: [
          TextButton(
            onPressed: () => Get.back(result: false),
            child: const Text('取消'),
          ),
          TextButton(
            onPressed: () => Get.back(result: true),
            style: TextButton.styleFrom(foregroundColor: Colors.red),
            child: const Text('删除'),
          ),
        ],
      ),
    );

    if (confirmed == true) {
      debugPrint('🗑️ ServerDockerController: 删除 Compose 项目 - $projectName');
      
      try {
        LoadingUtil.show('正在删除项目...');
        
        final client = _serverService.getClient(serverId);
        if (client == null) throw Exception('无法获取 SSH 客户端');
        
        final container = containers.firstWhere((c) => c.composeProject == projectName);
        final workDir = container.composeWorkingDir;
        
        if (workDir == null || workDir.isEmpty) {
          throw Exception('无法获取项目工作目录');
        }
        
        final composeCmd = await _getComposeCommand();
        final cmd = 'cd "$workDir" && $composeCmd down';
        debugPrint('📝 执行命令: $cmd');
        
        await client.run(cmd);
        
        debugPrint('✅ Compose 项目删除成功');
        LoadingUtil.success('项目删除成功');
        
        await loadContainers(showLoading: false);
      } catch (e) {
        debugPrint('❌ 删除 Compose 项目失败: $e');
        LoadingUtil.error('删除失败: $e');
      }
    }
  }

  @override
  void onClose() {
    debugPrint('🔚 ServerDockerController: onClose');
    _stateSubscription?.cancel();
    _refreshTimer?.cancel();
    super.onClose();
  }
}

